import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.*;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Created by Shine Kaye on 2016/10/21.
 */

class POIUtils {
    private String src;
    private InputStream in;
    private XWPFDocument doc;

    POIUtils(String src) throws IOException {
        this.src = src;
        in = new FileInputStream(src);
        doc = new XWPFDocument(in);
    }


    public void printText() throws IOException {
        XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
        String mainText = extractor.getText();
        System.out.println(mainText);

    }

    public void printCharCount() throws IOException {
        int charCountNoSpa = doc.getProperties().getExtendedProperties().getUnderlyingProperties().getCharacters();
        int charCount = doc.getProperties().getExtendedProperties().getUnderlyingProperties().getCharactersWithSpaces();
        System.out.println("（包含空格）全文总字数共 " + charCount + " 字");
        System.out.println("（不包含空格）全文总字数共 " + charCountNoSpa + " 字");
    }

    public void printParaCount() {
        List<XWPFParagraph> paras = doc.getParagraphs();
        int paraCount = paras.size();
        System.out.println("全文共有段落 " + paraCount + " 段");
    }

    public void printHierarchy() {
        List<XWPFParagraph> paras = doc.getParagraphs();
        List<String> list = new ArrayList<String>();
        System.out.println("全文的层级结构为：");
        for (XWPFParagraph para: paras) {
            String text = para.getParagraphText();
            String style = para.getStyle();
            if ("1".equals(style)) {
                System.out.println(text+"--["+style+"]");
            }else if ("2".equals(style)) {
                System.out.println(text+"--["+style+"]");
            }else if ("3".equals(style)) {
                System.out.println(text+"--["+style+"]");
            }else{
                continue;
            }
            list.add(text);
        }
    }



    public void replace(String destPath, Map<String, String> map) throws IOException {

        Iterator<XWPFParagraph> itPara = doc.getParagraphsIterator();
        while (itPara.hasNext()) {
            XWPFParagraph paragraph = itPara.next();
            List<XWPFRun> runs = paragraph.getRuns();
            for (int i = 0; i < runs.size(); i++) {
                String oneparaString = runs.get(i).getText(
                        runs.get(i).getTextPosition());
                for (Map.Entry<String, String> entry : map
                        .entrySet()) {
                    oneparaString = oneparaString.replace(
                            entry.getKey(), entry.getValue());
                }
                runs.get(i).setText(oneparaString, 0);
            }
        }

        Iterator<XWPFTable> itTable = doc.getTablesIterator();
        while (itTable.hasNext()) {
            XWPFTable table = itTable.next();
            int rcount = table.getNumberOfRows();
            for (int i = 0; i < rcount; i++) {
                XWPFTableRow row = table.getRow(i);
                List<XWPFTableCell> cells = row.getTableCells();
                for (XWPFTableCell cell : cells) {
                    String cellTextString = cell.getText();
                    for (Map.Entry<String, String> e : map.entrySet()) {
                        if (cellTextString.contains(e.getKey()))
                            cellTextString = cellTextString
                                    .replace(e.getKey(),
                                            e.getValue());
                    }
                    cell.removeParagraph(0);
                    cell.setText(cellTextString);
                }
            }
        }
        FileOutputStream outStream = new FileOutputStream(destPath);
        doc.write(outStream);
        outStream.close();
    }

}
